package com.df.server;

import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.handler.timeout.IdleStateEvent;

import java.net.InetSocketAddress;

public class WebSocketServerHandlerBak extends SimpleChannelInboundHandler<WebSocketFrame>
{

//    private static final Logger logger = LoggerFactory.getLogger(WebSocketFrameHandler.class);

    private ByteBuf tempByteBuf;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception
    {
        try
        {
            if (frame instanceof TextWebSocketFrame)
            {
               handleMessage(((TextWebSocketFrame) frame).text(), ctx.channel(), ctx);
            }
            else if (frame instanceof PingWebSocketFrame)
            {
                ctx.channel().write(new PongWebSocketFrame(frame.content()));
            }
            else if (frame instanceof BinaryWebSocketFrame)
            {
                ctx.close();

//                ByteBuf in = frame.content();
//                if (frame.isFinalFragment() == false)
//                {
//                    if (tempByteBuf == null)
//                    {
//                        tempByteBuf = ctx.alloc().heapBuffer();
//                    }
//                    tempByteBuf.writeBytes(in);
//                }
//                else
//                {
//                    handleMessage(in, ctx.channel(), ctx);
//                }
            }
            else if (frame instanceof ContinuationWebSocketFrame)
            {
//                tempByteBuf.writeBytes(frame.content());
//                if (frame.isFinalFragment() == true)
//                {
//                    handleMessage(tempByteBuf, ctx.channel(), ctx);
//                    tempByteBuf.clear();
//                }
            }
            else
            {
                System.out.println("channelRead0 error, unsupport webSocketFrame type = "+frame.getClass().getName());
                ctx.close();
            }
        }
        catch (Exception e)
        {
            InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
//            logger.error("channelRead0 error, ip = {}, exception = ", insocket.getAddress().getHostAddress(), e);
            System.out.println("channelRead0 error, ip = "+insocket.getAddress().getHostAddress()+", exception = "+e.getMessage());
        }
    }
    public void handleMessage(String stringMsg, Channel channel, ChannelHandlerContext ctx){

    }
    public void handleMessage(ByteBuf byteBuf, Channel channel, ChannelHandlerContext ctx)
    {
//        if (!MessageManager.getInstance().isAvailableForClient())
//        {
//            ForceOfflinePush.Builder builder = ForceOfflinePush.newBuilder();
//            builder.setForceOfflineReason(ForceOfflineReasonEnum.ForceOfflineServerNotAvailable);
//            NetMessage message = new NetMessage(RpcNameEnum.ForceOfflinePush_VALUE, builder);
//            write(message, channel);
//            channel.close();
//        }
//        else
//        {
//            int totalLength = byteBuf.readInt();
//            int rpcNum = byteBuf.readInt();
//            if (rpcNum == 900)
//            {
//                channel.attr(ChannelActor.NETTY_CHANNEL_TO_PING_TIME).set(System.currentTimeMillis());
//                sendPingMsg(ctx, 901, System.currentTimeMillis());
//                return;
//            }
//            // errorCode
//            byteBuf.readInt();
//            byte[] bytes = new byte[totalLength - 12];
//            byteBuf.readBytes(bytes);
//            if (rpcNum == Login.ReqReconnect.MsgID.eMsgID_VALUE)
//            {
//                if (!CheckReconnect(bytes, channel))//重连失败(logicServer上该玩家实际已下线) 这里回收玩家的actor 并且通知客户端直接走登录流程
//                {
//                    ActorRef actor = ChannelActor.getChannelActor(channel);
//                    if (actor != null)
//                    {
//                        actor.tell(PoisonPill.getInstance(),ActorRef.noSender());
//                    }
//                    Login.ResReconnectFail.Builder builder = Login.ResReconnectFail.newBuilder();
//                    NetMessage message = new NetMessage(Login.ResReconnectFail.MsgID.eMsgID_VALUE, builder);
//                    write(message, channel);
//                    return;
//                }
//            }
//            ActorRef actor = ChannelActor.attachChannelActor(channel);
////            logger.info(rpcNum + ":" + actor.getClass().getName());
//            NetMessage message = new NetMessage(rpcNum, bytes);
//            actor.tell(message, ActorRef.noSender());
//        }
    }

    /**
     * 请求断线重连 这里判断是否可以断线重连
     * @param bytes
     * @param channel
     * @return
     */
    private boolean CheckReconnect(byte[] bytes, Channel channel)
    {
//        try
//        {
//            Login.ReqReconnect.Builder builder = Login.ReqReconnect.newBuilder().mergeFrom(bytes);
//            String token = builder.getToken();
//            Channel oldChannel = ChannelActor.channelMap.get(token);
//            Integer logic = ChannelActor.logicIdMap.get(token);
//            if (logic != null && oldChannel != null && !oldChannel.equals(channel))
//            {
//
//                int sessionId = ChannelActor.getSessionId(oldChannel);
//                long userId = ChannelActor.getUserId(oldChannel);
//                int groupId = ChannelActor.getGroupId(oldChannel);
//
//                ActorRef newActor = MessageManager.getInstance().createChannelActor(channel);
//                channel.attr(ChannelActor.NETTY_CHANNEL_TO_ACTOR_KEY).set(newActor);
//                channel.attr(ChannelActor.NETTY_CHANNEL_TO_SESSION_ID_KEY).set(sessionId);
//                channel.attr(ChannelActor.NETTY_CHANNEL_TO_USER_ID_KEY).set(userId);
//                channel.attr(ChannelActor.NETTY_CHANNEL_TO_TOKEN_KEY).set(token);
//                channel.attr(ChannelActor.NETTY_CHANNEL_TO_GROUP_ID).set(groupId);
//                ChannelActor.channelMap.put(token, channel);
//                OnlineClientManager.getInstance().addSession(sessionId, channel);
//                ChannelActor.loadBalanceService.setOneSessionIdToLogicServerId(sessionId, logic);
//                OnlineClientManager.getInstance().addSession(sessionId, channel);
//                if (oldChannel.isActive()) {
//                    logger.error("重连时原连接还可以用");
//                    oldChannel.close();
//                }
//                return true;
//            }
//            logger.info("请求断线重连失败!!!{} hashcode:{},目标LogicId:{},token:{}",channel,channel.hashCode(),logic,token);
//        }catch (Exception e)
//        {
//            logger.error(e.getMessage(),e);
//        }
        return false;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx)
    {
//        if (!MessageManager.getInstance().isAvailableForClient())
//        {
//            logger.error("服务器不可用! isConnectToGm:" + MessageManager.getInstance().isConnectToGm);
//            ForceOfflinePush.Builder builder = ForceOfflinePush.newBuilder();
//            builder.setForceOfflineReason(ForceOfflineReasonEnum.ForceOfflineServerNotAvailable);
//            NetMessage message = new NetMessage(RpcNameEnum.ForceOfflinePush_VALUE, builder);
//            Channel channel = ctx.channel();
//            write(message, channel);
//            ctx.close();
//        }
    }

    // 当channel失效时（比如客户端断线或者服务器主动调用ctx.close），关闭channel对应的channelActor
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception
    {
//        ActorRef actor = ChannelActor.getChannelActor(ctx.channel());
//        if (actor != null)
//        {
//            NetMessage respMsg = new NetMessage(GlobalConstant.PLAYER_OFF_LINE, new byte[0]);
//            respMsg.setSessionId(0);
//            actor.tell(respMsg, ActorRef.noSender());
//            actor.tell(PoisonPill.getInstance(),ActorRef.noSender());
//        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception
    {
        if (evt instanceof IdleStateEvent)
        {
            ctx.close();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable throwable) throws Exception
    {
        ctx.close();
        if (!throwable.getMessage().startsWith("远程主机强迫关闭了一个现有的连接"))
        {
            InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
//            logger.error("exceptionCaught, ip = {}, exception = ", insocket.getAddress().getHostAddress(), throwable);
            System.out.println("exceptionCaught, ip = "+insocket.getAddress().getHostAddress()+", exception = "+throwable.getMessage());
        }
    }

//    private void write(IMessage message, Channel channel)
//    {
//        if (channel != null && channel.isActive() && channel.isWritable())
//        {
//            channel.writeAndFlush(message.toBinaryWebSocketFrame());
//        }
//    }

//    private void sendPingMsg(ChannelHandlerContext ctx, int msgId, long time)
//    {
//        Common.ResHeartBeat.Builder builder = Common.ResHeartBeat.newBuilder();
//        builder.setTime(time);
//        NetMessage respMsg = new NetMessage(msgId, builder);
//        ctx.channel().writeAndFlush(respMsg.toBinaryWebSocketFrame());
//    }

}
